
/*-------------------------------------------------------------------------
 *
 * tsmapi.h
 *	  表样本方法的 API
 *
 * Copyright (c) 2015-2022, PostgreSQL Global Development Group
 *
 * src/include/access/tsmapi.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef TSMAPI_H
#define TSMAPI_H

#include "nodes/execnodes.h"
#include "nodes/pathnodes.h"


/*
 * 回调函数签名 --- 更多信息见 tablesample-method.sgml。
 */

typedef void (*SampleScanGetSampleSize_function) (PlannerInfo *root,
												  RelOptInfo *baserel,
												  List *paramexprs,
												  BlockNumber *pages,
												  double *tuples);

typedef void (*InitSampleScan_function) (SampleScanState *node,
										 int eflags);

typedef void (*BeginSampleScan_function) (SampleScanState *node,
										  Datum *params,
										  int nparams,
										  uint32 seed);

typedef BlockNumber (*NextSampleBlock_function) (SampleScanState *node,
												 BlockNumber nblocks);

typedef OffsetNumber (*NextSampleTuple_function) (SampleScanState *node,
												  BlockNumber blockno,
												  OffsetNumber maxoffset);

typedef void (*EndSampleScan_function) (SampleScanState *node);

/*
 * TsmRoutine 是一个由 tablesample 方法的处理函数返回的结构体。
 * 它提供了调度器和执行器所需的回调函数指针，以及有关该方法的附加信息。
 *
 * 未来可能会添加更多的函数指针。
 * 因此，建议处理程序使用 makeNode(TsmRoutine) 初始化结构体，
 * 以便所有字段都设置为 NULL。这将确保没有字段意外地留为空未定义。
 */
typedef struct TsmRoutine
{
	NodeTag		type;

	/* TABLESAMPLE 子句参数的数据类型 OID 列表 */
	List	   *parameterTypes;

	/* 方法能否在查询之间，甚至在查询内部生成可重复样本？ */
	bool		repeatable_across_queries;
	bool		repeatable_across_scans;

	/* 在物理表上规划 SampleScan 的函数 */
	SampleScanGetSampleSize_function SampleScanGetSampleSize;

	/* 在物理表上执行 SampleScan 的函数 */
	InitSampleScan_function InitSampleScan; /* 可以为NULL */
	BeginSampleScan_function BeginSampleScan;
	NextSampleBlock_function NextSampleBlock;	/* 可以为NULL */
	NextSampleTuple_function NextSampleTuple;
	EndSampleScan_function EndSampleScan;	/* 可以为NULL */
} TsmRoutine;


/* access/tablesample/tablesample.c 中的函数 */
extern TsmRoutine *GetTsmRoutine(Oid tsmhandler);

#endif							/* TSMAPI_H */
